<?php
class Cierre extends AppModel{
    var $name = 'Cierre';
    var $belongsTo = array(
        'CentroDist'=>array(
            'className'=>'CentroDist',
            'foreignKey'=>'centro_dist_id'
        ),
        'Modulo'=>array(
            'className'=>'Modulo',
            'foreignKey'=>'modulo_id'
        ),
        'Ejercicio'=>array(
            'className'=>'Ejercicio',
            'foreignKey'=>'ejercicio_id'
        ),
        'Periodo'=>array(
            'className'=>'Periodo',
            'foreignKey'=>'periodo_id'
        )
    );
    var $hasMany = array(
        'ExcepcionesCierre'=>array(
            'className'=>'ExcepcionesCierre',
            'foreignKey'=>'cierre_id'
        )
    );

    function dateFilter($anyo, $mes = null, $dia = null, $datefield = 'fecha_emision'){
        $conditions = array('EXTRACT(\'year\' FROM '.$datefield.')'=>$anyo);
        if (!empty($mes)){
            $conditions += array(
                'EXTRACT(\'month\' FROM '.$datefield.')'=>$mes
            );
        }
        if (!empty($dia)){
            $conditions += array(
                'EXTRACT(\'day\' FROM '.$datefield.')'=>$dia
            );
        }
        return $conditions;
    }

    /**
     * Realiza el cierre de los documentos
     * @param array $models
     * @param int $empresa
     * @param int $centro_dist
     * @param int $ejercicio
     * @param int $periodo
     * @param date $fecha
     * @param array $usuario
     */
    private function cierreGenerico($modelos, $empresa, $centro_dist, $usuario, $anyo, $mes=null, $dia=null, $datefield = 'fecha_emision'){
        $realModels = array();
        foreach($modelos as $k=>$modelo){
            if (is_numeric($k)) array_push($realModels, $modelo);
            else array_push($realModels, $k);
        }
        $this->bindModel(array('belongsTo'=>$realModels));        
        foreach ($modelos as $k=>$modelo){
            if (is_numeric($k)) {
                $datefield = 'fecha_emision';
            } else {
                $datefield = $modelo;
                $modelo = $k;
            }
            $conditions = $this->dateFilter($anyo, $mes, $dia, $datefield);
            $documentos = $this->{$modelo}->find('all', array(
                'conditions'=>array_merge(array(
                    $modelo.'.empresa_id'=>$empresa,
                    $modelo.'.centro_dist_id'=>$centro_dist,
                    $modelo.'.activo'=>true,
                    $modelo.'.cerrado'=>false
                ), $conditions),
                'recursive'=>-1
            ));
            // chequear y cerrar
            $follow = true;
            foreach($documentos as $documento){
                if (isset($documento[$modelo]['numero_documento']) &&
                        $documento[$modelo]['numero_documento']==''){
                    $this->validationErrors['fecha_emision']="Documento #{$documento[$modelo]['numero_control']} sin numero";
                    $follow = true;
                    break;
                } else if (isset($documento[$modelo]['impreso']) &&
                        !$documento[$modelo]['impreso']){
                    $this->validationErrors['fecha_emision']="Documento #{$documento[$modelo]['numero_control']} pendiente de impresion";
                    $follow = true;
                    break;
                }
                $documento[$modelo]['cerrado'] = true;
                $documento[$modelo]['usuario_cierre_id'] = $usuario['id'];
                $documento[$modelo]['fecha_cierre'] = 'now()';
                $follow = $this->{$modelo}->save($documento);
                if (!$follow) break;
            }
            if (!$follow) break;
        }
        return $follow;
    }
    
    function cierreFacturacion($empresa, $centro_dist, $usuario, $anyo, $mes=null, $dia=null){
        // DocumentoVenta, ComprobantePercepcione
        $modelos = array('DocumentoVenta','ComprobantePercepcione','ReciboCobranza'=>'fecha');
        return $this->cierreGenerico($modelos, $empresa, $centro_dist, $usuario, $anyo, $mes, $dia);
    }

    function cierreCuentaCorriente($empresa, $centro_dist, $usuario, $anyo, $mes=null, $dia=null){
        $models = array('Convenio','NotaContabilidad');
        return $this->cierreGenerico($models, $empresa, $centro_dist, $usuario, $anyo, $mes, $dia);
    }

    function cierreAlmacen($empresa, $centro_dist, $usuario, $anyo, $mes=null, $dia=null){
        $models = array('GuiaRemisione','Ingreso','Salida','Transferencia', 'GuiaTransportista');
        return $this->cierreGenerico($models, $empresa, $centro_dist, $usuario, $anyo, $mes, $dia);
    }

    function cierreProduccion($empresa, $centro_dist, $usuario, $anyo, $mes=null, $dia=null){
        $models = array('Produccione','SolicitudMateriaPrima','TransferenciaProduccione');
        return $this->cierreGenerico($models, $empresa, $centro_dist, $usuario, $anyo, $mes, $dia);
    }

    function cierreCompras($empresa, $centro_dist, $usuario, $anyo, $mes=null, $dia=null){
        $models = array('Solicitude','Cotizacione','DocumentoCompra');
        return $this->cierreGenerico($models, $empresa, $centro_dist, $usuario, $anyo, $mes, $dia);
    }

    /**
     * Construye el filtro para consultar los cierres
     * @param int $empresa
     * @param int $anyo
     * @param int $mes
     * @param int $dia
     * @return array
     */
    function dateClosedFilter($empresa, $anyo, $mes = null, $dia = null){
        $ejercicio = $this->Ejercicio->find('first', array(
            'fields'=>array('id','activo','cerrado'),
            'conditions'=>array('codigo'=>$anyo),
            'recursive'=>-1
        ));
        if (!$ejercicio['Ejercicio']['activo'] || $ejercicio['Ejercicio']['cerrado'])
            return false;
        
        if (!empty($dia) && !empty($mes)){
            $conditions = array(
                0=>array(
                    'or'=>array(
                        0=>array('and'=>array('ejercicio_id'=>$ejercicio['Ejercicio']['id'],'periodo_id'=>$mes,'dia'=>null)),
                        1=>array('and'=>array('ejercicio_id'=>$ejercicio['Ejercicio']['id'],'periodo_id'=>null,'dia'=>null)),
                        2=>array('and'=>array('ejercicio_id'=>$ejercicio['Ejercicio']['id'],'periodo_id'=>$mes,'dia'=>$dia))
                    )
                )
            );
        } else if (empty($dia) && !empty($mes)){
            $conditions = array(
                0=>array(
                    'or'=>array(
                        0=>array('and'=>array('ejercicio_id'=>$ejercicio['Ejercicio']['id'],'periodo_id'=>null,'dia'=>null)),
                        1=>array('and'=>array('ejercicio_id'=>$ejercicio['Ejercicio']['id'],'periodo_id'=>$mes,'dia'=>$dia))
                    )
                )
            );
        } else {
            $conditions = array(
                0=>array(
                    'and'=>array('ejercicio_id'=>$ejercicio['Ejercicio']['id'],'periodo_id'=>$mes,'dia'=>$dia)
                )
            );
        }
        return $conditions;
    }
    /**
     * Para determinar si el modulo en la fecha indicada esta cerrado
     * @param int $empresa id de empresa
     * @param int $centro_dist id de centro de distribucion
     * @param int $modulo id de modulo
     * @param int $anyo año
     * @param int $mes mes
     * @param int $dia dia
     * @return boolean
     */
    function estaCerrado($empresa, $centro_dist, $modulo, $anyo, $mes=null, $dia=null){
        $arr = $this->dateClosedFilter($empresa, $anyo, $mes, $dia);
        if (!$arr) return false;
        
        $c = $this->find('count', array(
            'conditions'=>array(
                'empresa_id'=>$empresa,
                'centro_dist_id'=>$centro_dist,
                'modulo_id'=>$modulo
            ) + $arr,
            'recursive'=>-1
        ));
        return $c > 0;
    }
    /**
     * Para determinar si el usuario activo puede trabajar en el modulo con la fecha establecida
     * @param int $empresa id de empresa
     * @param int $centro_dist id de centro de distribucion
     * @param int $modulo id de modulo
     * @param array $usuario arreglo del usuario activo extraido de la session ($this->_usuario)
     * @param int $anyo año
     * @param int $mes mes
     * @param int $dia dia
     */
    function esExcepcion($empresa, $centro_dist, $modulo, $usuario, $anyo, $mes=null, $dia=null){
        if (!$this->estaCerrado($empresa, $centro_dist, $modulo, $anyo, $mes, $dia))
            return true; // si el modulo no esta cerrado en la fecha indicada devuelve true
        $arr = $this->dateClosedFilter($empresa, $anyo, $mes, $dia);
        if (!$arr) return true;
        $cierres = $this->find('list', array(
            'fields'=>array('id', 'modulo_id'),
            'conditions'=>array(
                'empresa_id'=>$empresa,
                'centro_dist_id'=>$centro_dist,
                'modulo_id'=>$modulo
            ) + $arr,
            'recursive'=>-1
        ));
        $this->bindModel(array('belongsTo'=>array('Aro')));
        $aros = $this->Aro->find('list',array(
            'fields'=>array('id', 'model'),
            'conditions'=>array(
                'or'=>array(
                    0=>array('and'=>array('model'=>'Usuario','foreign_key'=>$usuario['id'])),
                    1=>array('and'=>array('model'=>'Grupo','foreign_key'=>$usuario['grupo_id']))
                )
            ),
            'recursive'=>-1
        ));
        $excepciones = $this->ExcepcionesCierre->find('all', array(
            'fields'=>array('id','cierre_id','aro_id','fecha_inicial','fecha_final'),
            'conditions'=>array(
                'cierre_id'=>array_keys($cierres),
                'aro_id'=>array_keys($aros)
            ),
            'recursive'=>-1
        ));
        $now = strtotime(date('Y-m-d'));
        $result = false;
        foreach($excepciones as $excepcion){
            foreach($aros as $key=>$value){
                if (count($aros)>1 && $value=='Usuario' && $key==$excepcion['ExcepcionesCierre']['aro_id']){
                    $id = $key;
                } else if (count($aros)==1 && $key==$excepcion['ExcepcionesCierre']['aro_id']){
                    $id = $key;
                } else $id = null;
                
                if (!empty($id)){
                    if (empty($excepcion['ExcepcionesCierre']['fecha_inicial'])&&
                            empty($excepcion['ExcepcionesCierre']['fecha_final'])){ // sin fecha inicial ni final
                        $result = true;
                        break;
                    } else if (!empty($excepcion['ExcepcionesCierre']['fecha_inicial'])){ // solo con fecha inicial                        
                        $fecha = strtotime($excepcion['ExcepcionesCierre']['fecha_inicial']);
                        if ($now >= $fecha) $result = true;
                        break;
                    } else if (!empty($excepcion['ExcepcionesCierre']['fecha_final'])){ // solo con fecha final
                        $fecha = strtotime($excepcion['ExcepcionesCierre']['fecha_final']);
                        if ($now <= $fecha) $result = true;
                        break;
                    } else { // con fecha inicial y final
                        $fechai = strtotime($excepcion['ExcepcionesCierre']['fecha_inicial']);
                        $fechaf = strtotime($excepcion['ExcepcionesCierre']['fecha_final']);
                        if ($now >= $fechai && $now <= $fechaf) $result = true;
                        break;                        
                    }
                }
            }
        }
        return $result;
    }
}
?>
